#include<stdio.h>
#include<stdlib.h>  //堆管理

//五大内存分区
//栈空间：函数结束就消失
//文字常量区：无法修改
//代码段
//静态全局区:静态变量和全局变量
//堆：动态内存空间，申请和销毁都是由用户决定的

// void func()
// {
//     static int a= 10;
// }


int main()
{
    //malloc：申请一块堆上空间
    // malloc:申请空间可能失败，失败返回NULL
    // int *a=(int *)malloc(sizeof(int)); 
    // if(a== NULL)
    // {
    //     printf("堆上空间申请失败\n");
    //     return -1;
    // }
    // *a= 10;
    // printf("%d\n",*a);
    // //内存泄漏：堆上空间只申请，不释放
    // free(a); //释放内存

    // int *a= (int*)malloc(sizeof(int)*10);
    // if(a== NULL)
    // {
    //     printf("堆上空间申请失败\n");
    //     return -1;
    // }
    // for(int i=0; i<10; i++)
    // {
    //     a[i]= i+1;
    // }
    // for(int i=0; i<10 ;i++)
    // {
    //     printf("%d",a[i]);
    // }
    // printf("\n");

    // free(a);

    // int** a= (int**)malloc(sizeof(int*)*2);
    // if(a== NULL)
    // {
    //     printf("堆上空间申请失败\n");
    //     return -1;
    // }
    // for(int i=0; i<2; i++)
    // {
    //     a[i]=(int*)malloc(sizeof(int)*3); //每个指针继续申请
    // }

    // for(int i=0; i<2; i++)
    // {
    //     for(int j=0; j<3; j++)
    //     {
    //         a[i][j]= i*2+j;
    //         printf("%d",a[i][j]);
    //     }
    //     printf("\n");
    // }

    // for(int i=0;i<2;i++)
    // {
    //     free(a[i]);
    // }
    // free(a);

    //会将申请的每一块内存初始化为0, 更适合申请数组
    // calloc()
    int *a= (int*)calloc(10,sizeof(int));
    if(a==NULL)
    {
        printf("calloc申请空间失败！\n");
        return -1;
    }

    for(int i=0;i<10;i++)
    {
        a[i]=i+1;
        printf("%d",a[i]);
    }
    printf("\n");
    // free(a);

    //重新申请内存
    //扩容函数，将原本指向的堆上空间进行扩容
    //1、原地扩容，原指针仍然可以使用
    //2、重新申请空间，原指针的内存会被释放，原指针失效

    //默认原指针不再使用
    int *p= realloc(a,sizeof(int)*20);
    free(p);
    return 0;
}